/**
 * carousel 轮播模块
 * MIT Licensed
 */

layui.define('jquery', function (exports) {
  "use strict";

  var $ = layui.$
      , hint = layui.hint()
      , device = layui.device()

      //外部接口
      , carousel = {
        config: {} //全局配置项

        //设置全局项
        , set: function (options) {
          var that = this;
          that.config = $.extend({}, that.config, options);
          return that;
        }

        //事件
        , on: function (events, callback) {
          return layui.onevent.call(this, MOD_NAME, events, callback);
        }
      }

      //字符常量
      , MOD_NAME = 'carousel', ELEM = '.layui-carousel', THIS = 'layui-this',
      SHOW = 'layui-show', HIDE = 'layui-hide', DISABLED = 'layui-disabled'

      , ELEM_ITEM = '>*[carousel-item]>*', ELEM_LEFT = 'layui-carousel-left',
      ELEM_RIGHT = 'layui-carousel-right', ELEM_PREV = 'layui-carousel-prev',
      ELEM_NEXT = 'layui-carousel-next', ELEM_ARROW = 'layui-carousel-arrow',
      ELEM_IND = 'layui-carousel-ind'

      //构造器
      , Class = function (options) {
        var that = this;
        that.config = $.extend({}, that.config, carousel.config, options);
        that.render();
      };

  //默认配置
  Class.prototype.config = {
    width: '600px'
    , height: '280px'
    , full: false //是否全屏
    , arrow: 'hover' //切换箭头默认显示状态：hover/always/none
    , indicator: 'inside' //指示器位置：inside/outside/none
    , autoplay: true //是否自动切换
    , interval: 3000 //自动切换的时间间隔，不能低于800ms
    , anim: '' //动画类型：default/updown/fade
    , trigger: 'click' //指示器的触发方式：click/hover
    , index: 0 //初始开始的索引
  };

  //轮播渲染
  Class.prototype.render = function () {
    var that = this
        , options = that.config;

    options.elem = $(options.elem);
    if (!options.elem[0]) {
      return;
    }
    that.elemItem = options.elem.find(ELEM_ITEM);

    if (options.index < 0) {
      options.index = 0;
    }
    if (options.index
        >= that.elemItem.length) {
      options.index = that.elemItem.length - 1;
    }
    if (options.interval < 800) {
      options.interval = 800;
    }

    //是否全屏模式
    if (options.full) {
      options.elem.css({
        position: 'fixed'
        , width: '100%'
        , height: '100%'
        , zIndex: 9999
      });
    } else {
      options.elem.css({
        width: options.width
        , height: options.height
      });
    }

    options.elem.attr('lay-anim', options.anim);

    //初始焦点状态
    that.elemItem.eq(options.index).addClass(THIS);

    //指示器等动作
    if (that.elemItem.length <= 1) {
      return;
    }
    that.indicator();
    that.arrow();
    that.autoplay();
    that.events();
  };

  //重置轮播
  Class.prototype.reload = function (options) {
    var that = this;
    clearInterval(that.timer);
    that.config = $.extend({}, that.config, options);
    that.render();
  };

  //获取上一个等待条目的索引
  Class.prototype.prevIndex = function () {
    var that = this
        , options = that.config;

    var prevIndex = options.index - 1;
    if (prevIndex < 0) {
      prevIndex = that.elemItem.length - 1;
    }
    return prevIndex;
  };

  //获取下一个等待条目的索引
  Class.prototype.nextIndex = function () {
    var that = this
        , options = that.config;

    var nextIndex = options.index + 1;
    if (nextIndex >= that.elemItem.length) {
      nextIndex = 0;
    }
    return nextIndex;
  };

  //索引递增
  Class.prototype.addIndex = function (num) {
    var that = this
        , options = that.config;

    num = num || 1;
    options.index = options.index + num;

    //index不能超过轮播总数量
    if (options.index >= that.elemItem.length) {
      options.index = 0;
    }
  };

  //索引递减
  Class.prototype.subIndex = function (num) {
    var that = this
        , options = that.config;

    num = num || 1;
    options.index = options.index - num;

    //index不能超过轮播总数量
    if (options.index < 0) {
      options.index = that.elemItem.length - 1;
    }
  };

  //自动轮播
  Class.prototype.autoplay = function () {
    var that = this
        , options = that.config;

    if (!options.autoplay) {
      return;
    }
    clearInterval(that.timer);

    that.timer = setInterval(function () {
      that.slide();
    }, options.interval);
  };

  //箭头
  Class.prototype.arrow = function () {
    var that = this
        , options = that.config;

    //模板
    var tplArrow = $([
      '<button class="layui-icon ' + ELEM_ARROW + '" lay-type="sub">'
      + (options.anim === 'updown' ? '&#xe619;' : '&#xe603;') + '</button>'
      , '<button class="layui-icon ' + ELEM_ARROW + '" lay-type="add">'
      + (options.anim === 'updown' ? '&#xe61a;' : '&#xe602;') + '</button>'
    ].join(''));

    //预设基础属性
    options.elem.attr('lay-arrow', options.arrow);

    //避免重复插入
    if (options.elem.find('.' + ELEM_ARROW)[0]) {
      options.elem.find('.' + ELEM_ARROW).remove();
    }
    options.elem.append(tplArrow);

    //事件
    tplArrow.on('click', function () {
      var othis = $(this)
          , type = othis.attr('lay-type')
      that.slide(type);
    });
  };

  // 跳转到特定下标
  Class.prototype.jump = function (index) {
    var that = this;
    var options = that.config;

    if (index > options.index) {
      that.slide('add', index - options.index);
    } else if (index < options.index) {
      that.slide('sub', options.index - index);
    }
  }

  //指示器
  Class.prototype.indicator = function () {
    var that = this
        , options = that.config;

    //模板
    var tplInd = that.elemInd = $(['<div class="' + ELEM_IND + '"><ul>'
      , function () {
        var li = [];
        layui.each(that.elemItem, function (index) {
          li.push('<li' + (options.index === index ? ' class="layui-this"' : '')
              + '></li>');
        });
        return li.join('');
      }()
      , '</ul></div>'].join(''));

    //预设基础属性
    options.elem.attr('lay-indicator', options.indicator);

    //避免重复插入
    if (options.elem.find('.' + ELEM_IND)[0]) {
      options.elem.find('.' + ELEM_IND).remove();
    }
    options.elem.append(tplInd);

    if (options.anim === 'updown') {
      tplInd.css('margin-top', -(tplInd.height() / 2));
    }

    //事件
    tplInd.find('li').on(
        options.trigger === 'hover' ? 'mouseover' : options.trigger,
        function () {
          that.jump($(this).index());
        });
  };

  //滑动切换
  Class.prototype.slide = function (type, num) {
    var that = this
        , elemItem = that.elemItem
        , options = that.config
        , thisIndex = options.index
        , filter = options.elem.attr('lay-filter');

    if (that.haveSlide) {
      return;
    }

    //滑动方向
    if (type === 'sub') {
      that.subIndex(num);
      elemItem.eq(options.index).addClass(ELEM_PREV);
      setTimeout(function () {
        elemItem.eq(thisIndex).addClass(ELEM_RIGHT);
        elemItem.eq(options.index).addClass(ELEM_RIGHT);
      }, 50);
    } else { //默认递增滑
      that.addIndex(num);
      elemItem.eq(options.index).addClass(ELEM_NEXT);
      setTimeout(function () {
        elemItem.eq(thisIndex).addClass(ELEM_LEFT);
        elemItem.eq(options.index).addClass(ELEM_LEFT);
      }, 50);
    }

    //移除过度类
    setTimeout(function () {
      elemItem.removeClass(
          THIS + ' ' + ELEM_PREV + ' ' + ELEM_NEXT + ' ' + ELEM_LEFT + ' '
          + ELEM_RIGHT);
      elemItem.eq(options.index).addClass(THIS);
      that.haveSlide = false; //解锁
    }, 300);

    //指示器焦点
    that.elemInd.find('li').eq(options.index).addClass(THIS)
    .siblings().removeClass(THIS);

    that.haveSlide = true;

    // 回调返回的参数
    var params = {
      index: options.index
      , prevIndex: thisIndex
      , item: elemItem.eq(options.index)
    };

    typeof options.change === 'function' && options.change(params);
    layui.event.call(this, MOD_NAME, 'change(' + filter + ')', params);
  };

  //事件处理
  Class.prototype.events = function () {
    var that = this
        , options = that.config;

    if (options.elem.data('haveEvents')) {
      return;
    }

    //移入移出容器
    options.elem.on('mouseenter', function () {
      if (that.config.autoplay === 'always') {
        return;
      }
      clearInterval(that.timer);
    }).on('mouseleave', function () {
      if (that.config.autoplay === 'always') {
        return;
      }
      that.autoplay();
    });

    options.elem.data('haveEvents', true);
  };

  //核心入口
  carousel.render = function (options) {
    return new Class(options);
  };

  exports(MOD_NAME, carousel);
});

 
